//
// Created by admin on 2022/6/30.
//

#ifndef LEETCODE_COLLECTION_HPP
#define LEETCODE_COLLECTION_HPP

/*线程相关*/
#include "thread_pool_cpp.h"
#include <thread>
#include <mutex>
#include <windows.h>

/*C时间相关*/
#include <ctime>

/*字符串相关*/
#include <iostream>
#include <cstring>
#include <sstream>
#include <cassert>

/*lambda表达式相关*/
#include <functional>

/*容器和算法相关*/
#include <algorithm>
#include <vector>
#include <array>
#include <list>
#include <queue>
#include <stack>
#include <forward_list>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
//#include <hash_set> 已由unordered_set替换
//#include <hash_map> 已由unordered_map替换
#include <cmath>
#include <random>
/*自定义数据结构*/
/*自定义类型萃取工具*/
#include "type_trait.hpp"
#include "macros_deal.hpp"

template<typename ...> using cus_void_t = void;
template<typename ...> using cus_int_t = int;

/*由于模板类无法重载，目前只实现由模板函数实现的重载判断*/
#define REGISTER_LAMBDA_JUDGEMENT \
    template<typename T, typename ...Args>\
    auto lambda(int) -> decltype(declval<T>()(declval<Args>...), true_type{});\
    template<typename T, typename ...Args>\
    false_type lambda(...);\
    template<typename T, typename ...Args>\
    using is_lambda = decltype(lambda<T ,Args...>(0));\

#define REGISTER_METHOD_JUDGEMENT(name) \
    template<typename T, typename ...Args>\
    auto method_##name(int) -> decltype(declval<T>().name(declval<Args>...), true_type{});\
    template<typename T, typename ...Args>\
    false_type method_##name(...);\
    template<typename T, typename ...Args>\
    using has_method_##name = decltype(method_##name<T ,Args...>(0));\

#define REGISTER_FIELD_JUDGEMENT(name) \
    template<typename T>\
    auto field_##name(int) -> decltype(declval<T>().name, true_type{});\
    template<typename T>\
    false_type field_##name(...);\
    template<typename T>\
    using has_field_##name = decltype(field_##name<T>(0));\

/*方案一：重叠数组构建和初始化*/
#define overlap_CONTAINER_GENERATOR_REGISTER(name)\
    template<typename...>\
    struct name##Compile;\
    template<typename S, typename T>\
    struct name##Compile<S, T> {\
        using type = name<S>;\
    };\
    template<typename S, typename F, typename...R>\
    struct name##Compile<S, F, R...> : name##Compile<S, R...> {\
        using type = name<typename name##Compile<S, R...>::type>;\
    };\
\
    template<typename S, S s, typename F, typename RET=typename name##Compile<S, F>::type>\
    RET simple##name(F first) {\
        RET vs(first,s);\
        return vs;\
    }\
\
    template<typename S, S s, typename F, typename...R, typename RET=typename name##Compile<S, F, R...>::type>\
    RET simple##name(F first, R...rest) {\
        RET vs;\
        for (int i = 0; i < first; ++i) { vs.emplace_back(simple##name<S, s>(rest...)); }\
        return vs;\
    }


/*方案二：重叠数组构建和初始化，优化重叠类型获取判断*/
#define OVERLAP_CONTAINER_GENERATOR_REGISTER(name) \
\
    template<typename S, typename Gen, typename F, typename RET=name<S>>\
    RET overlap##name##G(Gen gen, F first) {          \
    static_assert(BaseTypeUtil::FunctionLike<Gen>::value,"Gen must be function type");\
        RET vs;\
        vs.reserve(first);\
        for (int i = 0; i < first; ++i ){ vs.emplace_back(gen());}\
        return vs;\
    }\
\
    template<typename S, typename Gen, typename F, typename...R,\
            typename RET=typename BaseTypeUtil::OverLapTypeHelper<S, sizeof...(R) + 1>::vectorType\
    >\
    RET overlap##name##G(Gen gen, F first, R...rest) {\
        static_assert(BaseTypeUtil::FunctionLike<Gen>::value,"Gen must be function type");\
        RET vs;\
        vs.reserve(first);\
        for (int i = 0; i < first; ++i) { vs.emplace_back(overlap##name##G<S, Gen,R...>(gen,rest...)); }\
        return vs;\
    }\
\
    template<typename S, S s, typename F, typename RET=name<S>>\
    RET overlap##name(F first) {\
        return RET (first, s);\
    }\
\
    template<typename S, S s, typename F, typename...R,\
            typename RET=typename BaseTypeUtil::OverLapTypeHelper<S, sizeof...(R)+1>::vectorType\
    >\
    RET overlap##name(F first, R...rest) {\
        RET vs;\
        for (int i = 0; i < first; ++i) { vs.emplace_back(overlap##name<S, s>(rest...)); }\
        return vs;\
    }\
\
    template<typename S, typename F, typename RET=name<S>>\
    RET overlap##name(F first) {\
        RET vs(first);\
        return vs;\
    }\
\
    template<typename S, typename F, typename...R,\
            typename RET=typename BaseTypeUtil::OverLapTypeHelper<S, sizeof...(R) + 1>::vectorType\
    >\
    RET overlap##name(F first, R...rest) {\
        RET vs;\
        for (int i = 0; i < first; ++i) { vs.emplace_back(overlap##name<S>(rest...)); }\
        return vs;\
    }

#define LAMBDA_WRAPPER_INTRO(func, intro...) \
    [](const decltype(intro)& args){\
        return func(args); \
    }

#define LAMBDA_WRAPPER(func, intro...) \
    [&(intro)]{\
        return func(intro); \
    }


namespace Util {
    using namespace std;

    /*可变参数处理模板, 用于逗号运算符处理可变参数*/
    struct VArgLoopDeal {
        template<class ...Args>
        VArgLoopDeal(Args &&...arg) {};

    };

#define VARG_DEAL(...) Util::VArgLoopDeal((__VA_ARGS__,0)...);

    template<typename T, typename U= T>
    inline T exchange(T &t, U &&u) {
        T oldVal = std::move(t);//要求T必须实现转移语句
        t = std::forward<U>(u);
        return oldVal;
    }

    template<class T>
    inline T *addressOf(const T &src) {
        /*首先强转成const volatile char&保证 src是在内存中同时是最细粒度char类型引用*/
        /*其次获取首地址去除cv修饰符*/
        /*最后强转成T* const T&可以一定程度上去除const修饰，一般指针都是值拷贝*/
        return (T *) ((char *) (&(const volatile char &) (src)));
    }

    /**
     *
     * TITLE 简易类型判断工具
     * */
    namespace BaseTypeUtil {
        /*是否是functional*/
        REGISTER_LAMBDA_JUDGEMENT

        /*判断是否是函数类型*/
        template<typename Ret, typename ...Args>
        struct FunctionLike : conditional<
                is_lambda<Ret, Args...>::value ||
                is_function<Ret(Args...)>::value, true_type, false_type>::type {
        };

        /*判断全部可变参数类型是否一致*/
        template<typename ...>
        struct AllSameType;

        template<typename A, typename ...REST>
        struct AllSameType<A, REST...> : AllSameType<REST...> {
            using compType = typename AllSameType<REST...>::anyType;
            constexpr static bool value = is_same<A, compType>::value && AllSameType<REST...>::value;
            using anyType = A;
        };

        template<typename A, typename B>
        struct AllSameType<A, B> {
            constexpr static bool value = is_same<A, B>::value;
            using anyType = A;
        };

        template<typename A>
        struct AllSameType<A> : true_type {
        };

        template<>
        struct AllSameType<> : true_type {
        };

        /*包装int类型模板，用于常量模板重载*/
        template<size_t N>
        struct Size_N {
            constexpr static size_t value = N;
        };

        /*包装可变类型，用于多参数重载*/
        template<size_t ...VN>
        struct Size_VN {
        };

        /*重叠类型辅助类*/
        template<typename T, size_t N>
        struct OverLapTypeHelper : OverLapTypeHelper<T, N - 1> {
            using initListType = initializer_list<typename OverLapTypeHelper<T, N - 1>::initListType>;
            using vectorType = vector<typename OverLapTypeHelper<T, N - 1>::vectorType>;
        };

        template<typename T>
        struct OverLapTypeHelper<T, 1> {
            using initListType = initializer_list<T>;
            using vectorType = vector<T>;
        };

        /*模拟重叠类数组实现包装*/
        template<typename T, size_t N>
        struct OverLapInitList : OverLapTypeHelper<T, N>::initListType {
            using initListType = typename OverLapTypeHelper<T, N>::initListType;

            OverLapInitList(initListType &&list) : initListType(list) {}
        };

        /*默认构造器*/
        template<typename T>
        struct DefaultGenerator {
            T operator()() {
                return T();
            }
        };
    }

    /**
     * TITLE 用于获取随机数工具
     * */
    namespace RandomUtil {
        static std::default_random_engine eg(time(nullptr));

        /*随机产生成函数*/
        template<typename T>
        inline T getRandom(const T &a, const T &b) {
            return T();
        }

        template<>
        inline double getRandom(const double &a, const double &b) {
            std::uniform_real_distribution<double> u(a, b); // 左闭右闭区间
            return u(eg);
        }

        template<>
        inline int getRandom(const int &a, const int &b) {
            return (int) getRandom < double > ((double) const_cast<int &>(a), (double) const_cast<int &>(b));
        }

    }

    /**
     *
     * TITLE 可变参数处理
     * */
    namespace VargUtil {
        using namespace std;
        /*类型参数个数萃取*/
        template<typename ...>
        struct VargTrait;

        template<>
        struct VargTrait<> {
        };

        template<typename T>
        struct VargTrait<T> {
            constexpr static int value = 1;
        };

        template<typename F, typename ...R>
        struct VargTrait<F, R...> : VargTrait<R...> {
            constexpr static int value = VargTrait<R...>::value + 1;
        };

        /*获取可变参数对应顺序类型*/
        template<size_t n, typename ...REST>
        struct VargAt;

        template<size_t n, typename T, typename ... REST>
        struct VargAt<n, VargTrait<T, REST...>> {
            using valueType = typename VargAt<n - 1, VargTrait<REST...>>::valueType;
            using vargTraitType = typename VargAt<n - 1, VargTrait<REST...>>::vargTraitType;
        };

        template<typename T, typename ... REST>
        struct VargAt<0, VargTrait<T, REST...>> {
            using valueType = T;
            using vargTraitType = VargTrait<T, REST...>;
        };


        template<>
        struct VargAt<0, VargTrait<>> {
            using valueType = VargTrait<>;
            using vargTraitType = VargTrait<>;
        };

        /*不依赖VargTrait的位置入参萃取*/
        template<size_t n, typename T, typename ... REST>
        struct VargAt<n, T, REST...> : VargAt<n - 1, REST...> {
            using type = typename VargAt<n - 1, REST...>::type;
        };

        template<typename T, typename ... REST>
        struct VargAt<0, T, REST...> {
            using type = T;
        };

        template<>
        struct VargAt<0> {
            using type = cus_void_t<>;
        };


        /*tuple类型（具象化可变参数）迭代*/
        /*方案1*/
        template<size_t N, typename ...ARG>
        struct TupleLikeHandle {
            using TupleLike = tuple<ARG...>;

            static ostream &invoke(ostream &os, const TupleLike &tupleLike) {
                TupleLikeHandle<N - 1, ARG...>::invoke(os, tupleLike);
                if (N != VargTrait<ARG...>::value) {
                    os << get<N - 1>(tupleLike) << ", ";
                } else {
                    os << get<N - 1>(tupleLike);
                }
                return os;
            }
        };

        template<typename ...ARG>
        struct TupleLikeHandle<1, ARG...> {
            using TupleLike = tuple<ARG...>;

            static ostream &invoke(ostream &os, const TupleLike &tupleLike) {
                return os << get<0>(tupleLike) << ", ";
            }
        };

        /*方案2*/
        struct TupleHelper {
            template<class ...ARGS, size_t N = sizeof...(ARGS)>
            static ostream &invoke(ostream &os, const tuple<ARGS...> &tuple) {
                return doPrint<N, ARGS...>(os, tuple, BaseTypeUtil::Size_N<N>());
            }

        private:
            template<size_t N, class ...ARGS, size_t LEN = sizeof...(ARGS)>
            static ostream &
            doPrint(ostream &os, const tuple<ARGS...> &tuple, BaseTypeUtil::Size_N<N> = BaseTypeUtil::Size_N<N>()) {
                doPrint < N - 1, ARGS...>(os, tuple, BaseTypeUtil::Size_N<N - 1>());
                if (LEN != N) {
                    os << get<N - 1>(tuple) << ", ";
                } else {
                    os << get<N - 1>(tuple);
                }
                return os;
            }

            template<size_t N = 1, class ...ARGS>
            static ostream &doPrint(ostream &os, const tuple<ARGS...> &tuple,
                                    const BaseTypeUtil::Size_N<1> & = BaseTypeUtil::Size_N<1>()) {
                return os << get<0>(tuple) << ", ";
            }
        };

    }


    /**
     * TITLE 简易数组转换
     * */
    namespace VectorUtil {
//        using namespace BaseTypeUtil;
//        using namespace VargUtil;
//        OVERLAP_CONTAINER_GENERATOR_REGISTER(vector)

        /*支持vector多维度快速创建*/
        OVERLAP_CONTAINER_GENERATOR_REGISTER(vector)

        /*简易initList*/
        /*注意C++针对const 常量优先匹配const T& 其次 T&&*/
        template<typename T, size_t N = 1,
                typename RET = typename BaseTypeUtil::OverLapTypeHelper<T, N>::vectorType,
                typename INTRO = typename BaseTypeUtil::OverLapTypeHelper<T, N>::initListType
        >
        RET arr2Vector(const INTRO &introArr, BaseTypeUtil::Size_N<N> = BaseTypeUtil::Size_N<N>()) {
            return RET(introArr);
        }

        template<typename T, size_t N,
                typename RET = typename BaseTypeUtil::OverLapTypeHelper<T, N>::vectorType,
                typename INTRO = typename BaseTypeUtil::OverLapTypeHelper<T, N>::initListType
        >
        typename enable_if<N >= 2, RET>::type
        arr2Vector(INTRO &&introArr, BaseTypeUtil::Size_N<N> = BaseTypeUtil::Size_N<N>()) {
            RET vs;
            vs.reserve(introArr.size());
            for (int i = 0; i < introArr.size(); ++i) {
                vs.emplace_back(arr2Vector < T, N - 1 > (*(introArr.begin() + i)));
            }
            return vs;
        }

        /*注意模板推导是从模板本身的参数开始的，内部属性类型是无法反推类本身的模板参数的(不可以通过模板内部属性的结果反推模板类本身得类型)*/
        /*函数的匹配和重找优先级永远都是函数本身的参数类型，其次才是模板类型*/
        /*example: arr2Vector<int,2>({{1,2},{2,3}}) */
        template<typename T, size_t N,
                typename INTRO =BaseTypeUtil::OverLapInitList<T, N>,
                typename INTRO_LIST =typename INTRO::initListType,
                typename RET = typename BaseTypeUtil::OverLapTypeHelper<T, N>::vectorType
        >
        RET arr2Vector(const BaseTypeUtil::OverLapInitList<T, N> &introArr) {
            return arr2Vector < T, N > (move(static_cast<const INTRO_LIST &>(introArr)), BaseTypeUtil::Size_N<N>());
        }

    }

    /**
     *
     * TITLE 简易的反射工具
     * */
    namespace ReflectUtil {
        /*size方法判断*/
        REGISTER_METHOD_JUDGEMENT(size)
        /*begin方法判断*/
        REGISTER_METHOD_JUDGEMENT(begin)
        /*end方法判断*/
        REGISTER_METHOD_JUDGEMENT(end)
        /*c_str方法判断*/
        REGISTER_METHOD_JUDGEMENT(c_str)

    }


//    using namespace ReflectUtil;
//    using namespace BaseTypeUtil;
//    using namespace VargUtil;
//    using namespace VectorUtil;
//    using namespace RandomUtil;
//    using namespace TypeTrait;
//    using namespace ThreadPool;



}

/*简易输出工具*///TODO
namespace PrintHelper {
    using namespace Util::ReflectUtil;
    /*可重入锁*/
    static std::mutex mut;

    /*pair类型流式输出*/
    template<typename F, typename S>
    std::ostream &operator<<(std::ostream &os, const std::pair<F, S> &p) {
        return os << "(" << p.first << ", " << p.second << ")";
    }


    /*tuole类型流式输出*/
    template<typename ...ARG>
    std::ostream &operator<<(std::ostream &os, const std::tuple<ARG...> &p) {
        os << "(";
//        TupleLikeHandle<VargTrait<ARG...>::value, ARG...>::invoke(os, p) << ")";
        Util::VargUtil::TupleHelper::invoke(os, p) << ")";
        return os;
    }

    /*可迭代类型容器流式输出*/
    template<template<typename, typename...> class Cont, typename T, typename... Types>
    typename std::enable_if<
            has_method_begin<Cont<T, Types...>>::value &&
            has_method_end<Cont<T, Types...>>::value &&
            has_method_size<Cont<T, Types...>>::value &&
            !has_method_c_str<Cont<T, Types...>>::value, std::ostream &>::type
    operator<<(std::ostream &os, const Cont<T, Types...> &cntr) {
        os << "{";
        for (auto itr = cntr.begin(); itr != cntr.end(); itr = std::next(itr)) {
            os << *itr;
            if (std::next(itr) != cntr.end()) {
                os << ", ";
            }
        }
        return os << "}";
    }


    template<typename ...T>
    std::string toString(const T &...t) {
        std::stringstream ss;
        Util::VArgLoopDeal{(ss << t)...};
        return ss.str();
    }

    /*格式化字符串*/
    template<size_t oldlen = BUFSIZ, typename ...Args>
    inline std::string format_string(const char *format, Args &&... args) {
        char buffer[oldlen]; // 默认栈上的缓冲区

        size_t newlen = std::snprintf(&buffer[0], oldlen, format, std::forward<Args>(args)...);
        newlen++; // 算上终止符'\0'

        if (newlen > oldlen) { // 默认缓冲区不够大，从堆上分配
            std::unique_ptr<char> bp((char *) std::malloc(newlen));
            std::snprintf(bp.get(), newlen, format, std::forward<Args>(args)...);
            return bp.get();
        }
        return buffer;
    }

    template<typename ...R>
    inline void printOut(const R &...r) {
        Util::VArgLoopDeal{(std::cout << r)..., std::cout << std::endl};
    }

    template<typename ...R>
    inline void printOutL(const R &...r) {
        std::unique_lock<std::mutex> rm_lock(mut);
        printOut(r...);
    }

}
namespace PrintHelperItf {
/*TODO 支持string类型格式化输入出*/
#define printLn(args...) \
        PrintHelper::printOut(args)

#define printLnL(args...) \
        PrintHelper::printOutL(args)


#define formatString(format, args...) \
        PrintHelper::format_string(format, args)

#define fPrintLn(format, args...) \
       PrintHelper::printOut(PrintHelper::format_string(format, args))

#define fPrintLnL(format, args...) \
       PrintHelper::printOutL(PrintHelper::format_string(format, args))


#define STRING(args...) \
       PrintHelper::toString(args)

#define C_STRING(args...) \
       PrintHelper::toString(args).data()

}

/*简易debug工具*/
namespace DebugHelper {
//    using namespace TypeTrait;
//    using namespace Util;

    template<typename ...T>
    static void
    debugArgsType(const TypeTrait::LogWrapper &logWrapper, std::tuple<const char *, const char *, T> &&...tps) {
        static_assert(sizeof...(T) > 0, "intro args nums must be bigger than ZERO!");
        std::cout << "line of " << logWrapper << " with debug args info: " << std::endl;
        int index = 0;
        Util::VArgLoopDeal{
                (printLn(++index, "\t", std::get<0>(tps), " ( ", std::get<1>(tps), " = ", std::get<2>(tps), " ) ")
                        , 0)...
        };
    }

    template<typename T>
    static void debug_impl(const char **typeP, const char **nameP, T &&value) {
        std::cout <<
                  ANSI_PURPLE(*nameP) <<
                  ANSI_RED(" = ") <<
                  ANSI_DBG(C_STRING(value)) <<
                  ANSI_RED(" ( ") <<
                  ANSI_GREEN(*typeP) <<
                  ANSI_RED(")") << std::endl;
    }

    template<typename T, typename... U>
    static void debug_impl(const char **exprs,
                           const char **types,
                           T &&value,
                           U &&... rest) {
        debug_impl(exprs, types, std::forward<T>(value));
        debug_impl(const_cast<const char **>(exprs + 1), const_cast<const char **>(types + 1),
                   std::forward<U>(rest)...);
    }

    template<typename ...T>
    static void debug(const TypeTrait::LogWrapper &logWrapper,
                      std::initializer_list<const char *> &&typeList,
                      std::initializer_list<const char *> &&nameList,
                      T &&...values
    ) {
        static_assert(sizeof...(T) > 0, "intro args nums must be bigger than ZERO!");
        std::cout << "line of " << logWrapper << " with debug args info: " << std::endl;
        debug_impl(const_cast<const char **>(typeList.begin()), const_cast<const char **>( nameList.begin()),
                   std::forward<T>(values)...);
    }


#define TYPE_NAME(arg) TypeTrait::fullTypeName<decltype(arg)>()

#define WITH_NAME_TYPE_1(arg) {TYPE_NAME(arg),STRING_FY(arg),arg}
#define WITH_NAME_TYPE_2(arg) std::make_tuple(TYPE_NAME(arg),STRING_FY(arg),arg)
#define EXPAND_ARGS_WITH_NAME_TYPE_1(...)  {JOIN(LOOP_DEAL_V_, COUNT_ARGS(__VA_ARGS__))(WITH_NAME_TYPE_1,(__VA_ARGS__))}
#define EXPAND_ARGS_WITH_NAME_TYPE_2(...)  JOIN(LOOP_DEAL_V_, COUNT_ARGS(__VA_ARGS__))(WITH_NAME_TYPE_2,(__VA_ARGS__))

#define EXPAND_ARGS_WITH_CALL(fn, ...) {JOIN(LOOP_DEAL_V_, COUNT_ARGS(__VA_ARGS__))(fn,(__VA_ARGS__))}
#define DEBUG(...) DebugHelper::debugArgsType(FILE_LINE,EXPAND_ARGS_WITH_NAME_TYPE_2(__VA_ARGS__))

/*example: DBG(a1,fn1,...)*/
#define DBG(...) DebugHelper::debug(FILE_LINE,EXPAND_ARGS_WITH_CALL(TYPE_NAME,__VA_ARGS__),EXPAND_ARGS_WITH_CALL(STRING_FY,__VA_ARGS__),__VA_ARGS__)

}
/*简易效率评比工具*/
namespace CalculateUtil {
    using namespace std;
    using namespace PrintHelper;
    static std::mutex mt;

    /*微秒级计时器（windows平台依赖）*/
    class TimeWatch {
        LARGE_INTEGER freq_{};
        LARGE_INTEGER start_{};
        LARGE_INTEGER end_{};
        long long elapsed_{0};

    public:
        TimeWatch() {
            QueryPerformanceFrequency(&freq_);
        }

        virtual ~TimeWatch() = default;

    public:
        void resetAndStart() {
            QueryPerformanceCounter(&start_);
        }

        void stopAndWatch() {
            QueryPerformanceCounter(&end_);
            elapsed_ = (end_.QuadPart - start_.QuadPart) * 1e6 / double(freq_.QuadPart);
        }

        inline double countSeconds() const {
            return double(elapsed_) / 1e6;

        }

        inline double countMs() const {
            return double(elapsed_) / 1e3;
        }

        inline double countUs() const {
            return double(elapsed_);
        }

    };


    /*简易benchmark测试*/
    template<typename F, typename S>
    static void
    doCountTimeConsume(const pair<F, S> &intro) {
        static_assert(Util::BaseTypeUtil::FunctionLike<S>::value, "the second arg is must be functional!");
        TimeWatch timeWatch;
        timeWatch.resetAndStart();
        intro.second();
        timeWatch.stopAndWatch();
        auto beautify = format_string("%-15s 耗时：%6.0fus|%4.3fms|%4.3fss", intro.first, timeWatch.countUs(),
                                      timeWatch.countMs(), timeWatch.countSeconds());
        std::lock_guard<std::mutex> onLock{mt};
        std::cout << beautify << std::endl;
    }

    template<typename F, typename S>
    static void
    doCountTimeConsume(const F &info, const S &func, int times = 1) {
        static_assert(Util::BaseTypeUtil::FunctionLike<S>::value,
                      "there must be two args and second arg is must be functional!");
        for (int i = 0; i < times; ++i) {
            doCountTimeConsume(make_pair(info, func));
        }
    }


    // 函数模板,不能获取函数模板的地址(必须要实例化).
    // 编译器将函数模板视为无限重载集, 直接利用实例化类型是无法推断函数实例的（如果仅依靠类型推导不出的函数重载，有必要依靠参数推导（C++11建议使用lambda表达式包装））
    template<template<typename, typename ...> class CONT, typename F = const char *, typename S = function<void()>, typename T = pair<F, S>, typename ...REST>
    static void multiCountTimeConsumeAsync(const CONT<T, REST...> &pl) {
        ThreadPool::SimplePool pool;
        for (auto itr = pl.begin(); itr != pl.end(); itr = std::next(itr)) {
            PrintFullTypeName(CONT<T, REST...>, decltype(pl), decltype(*itr));
            pool.commit(
                    [itr] { doCountTimeConsume(*itr); }
            );

        }
    }

    static void multiCountTimeConsumeAsync(initializer_list<pair<const char *, function<void()>>> &&pl) {
        ThreadPool::SimplePool pool;
        for (const auto &itr: pl) {
            pool.commit(
                    [&itr] { doCountTimeConsume(itr); }
            );
        }
    }

    static void multiCountTimeConsume(initializer_list<pair<const char *, function<void()>>> &&pl) {
        ThreadPool::SimplePool pool;
        for (const auto &itr: pl) {
            doCountTimeConsume(itr);
        }
    }


#define SimpleBenchMark(args...) \
                          CalculateUtil::doCountTimeConsume(args) \

#define MultiBenchMarkAsync(args...) \
                          CalculateUtil::multiCountTimeConsumeAsync(args) \

#define MultiBenchMark(args...) \
                          CalculateUtil::multiCountTimeConsume(args) \

}

/*简易tuple转函数入参处理，兼容C函数模式处理*/
namespace TupleHandleUtil {
    using namespace INDEX_TEMPLATE;

#define REG_TUPLE2FUNC_HANDLE_METHOD(nums) \
        template<typename Fn, typename TupleType, int...N>\
    static inline auto\
    tuple2IntroArgsHandle_##nums##_impl(Fn &&fn, const TupleType &tp, INDEX_TEMPLATE::Seq<N...>) ->\
    typename std::enable_if<sizeof...(N) == 0, decltype(fn())>::type {\
        return fn();\
    }\
\
    template<typename Fn, typename TupleType, int...N>\
    static inline auto\
    tuple2IntroArgsHandle_##nums##_impl(Fn &&fn, const TupleType &tp, INDEX_TEMPLATE::Seq<N...>) ->\
    typename std::enable_if<sizeof...(N) != 0, decltype(fn(std::get<N+nums>(tp)...))>::type {\
        return fn(std::get<N+nums>(tp)...);\
    }\
\
    template<typename Fn, typename ...ARGS>\
    static inline auto\
    tuple2IntroArgsHandle_##nums(Fn &&fn, const std::tuple<ARGS...> &tuple) -> decltype(tuple2IntroArgsHandle_##nums##_impl(std::forward<Fn>(fn),\
                                                                                                           tuple,\
                                                                                                           INDEX_TEMPLATE::Index<\
                                                                                                                   (int) (sizeof...(ARGS)) -\
                                                                                                                   1-nums>{})) {\
        return tuple2IntroArgsHandle_##nums##_impl(std::forward<Fn>(fn), tuple, INDEX_TEMPLATE::Index<(int) (sizeof...(ARGS)) - 1-nums>{});\
    }

    REG_TUPLE2FUNC_HANDLE_METHOD(0)

    REG_TUPLE2FUNC_HANDLE_METHOD(1)

    REG_TUPLE2FUNC_HANDLE_METHOD(2)

    REG_TUPLE2FUNC_HANDLE_METHOD(3)

#define TUPLE2FUNC_DEAL(nums, fn, tuple) TupleHandleUtil::tuple2IntroArgsHandle_##nums(fn,tuple)

}

#endif //LEETCODE_COLLECTION_HPP
